package com.mac.hosp_pre.admin.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.mac.hosp_pre.admin.entity.Hospital;
import com.mac.hosp_pre.admin.model.req.HospitalReqDto;
import com.mac.hosp_pre.admin.service.HospitalService;
import com.mac.hosp_pre.except.ResultCodeEnum;
import com.mac.hosp_pre.except.ServiceException;
import com.mac.hosp_pre.admin.model.req.HospitalQueryReqDto;
import com.mac.hosp_pre.admin.model.resp.HospitalRespDto;
import com.mac.hosp_pre.reply.PageResult;
import com.mac.hosp_pre.admin.service.DictService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Slf4j
@Service
public class HospitalServiceImpl extends BaseMongoServiceImpl<Hospital> implements HospitalService {

    @Autowired
    private DictService dictService;

    @Override
    public void add(HospitalReqDto req) {
        if (StringUtils.isBlank(req.getHospCode())){
            throw new ServiceException(ResultCodeEnum.PARAM_EMPTY_ERROR.getCode(),"医院编号不能为空");
        }
        Hospital hosp = new Hospital();
        hosp.setHospCode(req.getHospCode());
        Hospital one = super.findOne(hosp);
        //判断
        if(Objects.nonNull(one)) {
            hosp.setState(hosp.getState());
            one.setUpdateTime(new Date());
            one.setDeleted(false);
            super.updateById(one.getId(),one);
        } else {
            Hospital entity = new Hospital();
            BeanUtils.copyProperties(req,entity);
            Date date = new Date();
            entity.setCreateTime(date);
            entity.setUpdateTime(date);
            entity.setDeleted(false);
            super.save(entity);
        }
    }

    @Override
    public HospitalRespDto getByHospCode(String hospCode) {
        Hospital hospital = super.findOne(new Query(Criteria.where("hospCode").is(hospCode)));
        if (Objects.nonNull(hospital)) {
            HospitalRespDto hospitalRespDto = new HospitalRespDto();
            BeanUtils.copyProperties(hospital,hospitalRespDto);
            return hospitalRespDto;
        }
        return null;
    }

    @Override
    public PageResult<HospitalRespDto> selectHospPage(HospitalQueryReqDto hospitalQuery) {
        // 创建Pageable对象，设置当前页和每页记录数
        PageRequest pageable = PageRequest.of(hospitalQuery.getPageNo()-1,hospitalQuery.getPageSize(),Sort.by(Sort.Direction.DESC,"updateTime"));
        // 创建对象
        Hospital hosp = new Hospital();
        BeanUtils.copyProperties(hospitalQuery,hosp);
        PageResult<Hospital> pageResult = super.findPageByCondition(pageable, hosp);
        if (CollectionUtil.isNotEmpty(pageResult.getList())){
            List<HospitalRespDto> respDtoList = pageResult.getList().stream().map(item -> {
                HospitalRespDto respDto = new HospitalRespDto();
                BeanUtils.copyProperties(item,respDto);
                return respDto;
            }).collect(Collectors.toList());
            return new PageResult<>(respDtoList,pageResult.getTotal(),pageResult.getPageSize(),pageResult.getPageNo());
        }
        return PageResult.empty();
    }

    @Override
    public void updateStatus(String id, Integer status) {
        //根据id查询医院信息
        Hospital hospital = super.findOne(new Query(Criteria.where("id").is(id)));
        if (hospital == null){
            throw new ServiceException(ResultCodeEnum.NOT_EXISTS_ERROR);
        }
        //设置修改的值
        hospital.setState(status);
        hospital.setUpdateTime(new Date());
        super.updateById(hospital.getId(),hospital);
    }

    @Override
    public HospitalRespDto getHospById(String id) {
        return this.setHospitalHosType(super.findOne(new Query(Criteria.where("id").is(id))));
    }

    @Override
    public String getHospName(String hospCode) {
        Hospital hospital = super.findOne(new Query(Criteria.where("hospCode").is(hospCode)));
        if(hospital != null) {
            return hospital.getHospName();
        }
        return null;
    }

    @Override
    public List<HospitalRespDto> findByHospName(String hospName) {
        Pattern pattern= Pattern.compile("^.*"+hospName+".*$", Pattern.CASE_INSENSITIVE);
        List<Hospital> hospitals = super.find(new Query(Criteria.where("hospName").regex(pattern)));
        if (CollectionUtil.isNotEmpty(hospitals)) {
            return hospitals.stream().map(item -> {
                HospitalRespDto respDto = new HospitalRespDto();
                BeanUtils.copyProperties(item,respDto);
                return respDto;
            }).collect(Collectors.toList());
        }
        return null;
    }

    @Override
    public HospitalRespDto getPreBookRule(String hospCode) {
        Hospital hospital = super.findOne(new Query(Criteria.where("hospCode").is(hospCode)));
        return this.setHospitalHosType(hospital);
    }

    //获取查询list集合，遍历进行医院等级封装
    private HospitalRespDto setHospitalHosType(Hospital hospital) {
        if (hospital == null) {
            return null;
        }
        HospitalRespDto respDto = new HospitalRespDto();
        BeanUtils.copyProperties(hospital,respDto);
        //根据dictCode和value获取医院等级名称
        String hostypeString = dictService.getDictName("Hostype", hospital.getHospType());
        //查询省 市  地区
        String provinceString = dictService.getDictName("",hospital.getProvinceCode());
        String cityString = dictService.getDictName("",hospital.getCityCode());
        String districtString = dictService.getDictName("",hospital.getDistrictCode());
        respDto.setFullAddress(provinceString+"/"+cityString+"/"+districtString);
        respDto.setHospTypeName(hostypeString);
        return respDto;
    }
}
